package com.lhkk.inventoryvehicle

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.ImageFormat
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.util.Size
import android.view.View
import android.widget.Toast
import android_serialport_api.ComPort
import android_serialport_api.InitDeviceCallback
import androidx.camera.core.CameraSelector
import androidx.camera.core.FocusMeteringAction
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.Preview
import androidx.camera.core.SurfaceOrientedMeteringPointFactory
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import com.cj.mvvmlib.base.activity.BaseVmActivity
import com.lhkk.inventoryvehicle.ai.VehicleAnalyzerLeftToRight
import com.lhkk.inventoryvehicle.ai.VehicleAnalyzerRightToLeft
import com.lhkk.inventoryvehicle.ai.VehicleState
import com.lhkk.inventoryvehicle.common.GlobalVariables
import com.lhkk.inventoryvehicle.common.LogFileUtils
import com.lhkk.inventoryvehicle.databinding.ActivityMainBinding
import com.lhkk.inventoryvehicle.entity.CarEntity
import com.lhkk.inventoryvehicle.entity.StockStatus
import com.lhkk.inventoryvehicle.led.CMD
import com.lhkk.inventoryvehicle.led.LedManager
import com.lhkk.inventoryvehicle.rfid.RfidManager
import java.io.File
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


class MainActivity : BaseVmActivity<MainViewModel>() {

    private lateinit var mainBinding: ActivityMainBinding
    private lateinit var cameraExecutor: ExecutorService
    private var carEntity = CarEntity() //创建车辆
    private var epcSet = mutableSetOf<String>()
    private var isVerifying = false //是否在验证中
    private var outFrontResId = ""
    private var outMiddleResId = ""
    private var outEndResId = ""
    private var inFrontResId = ""
    private var inMiddleResId = ""
    private var inEndResId = ""
    private var currentCamera = 1
    private var imageCapture: ImageCapture? = null
    private lateinit var analyzer: Any
    override fun useTitleBar(): Boolean {
        return false
    }

    override fun layoutId(): View {
        mainBinding = ActivityMainBinding.inflate(layoutInflater)
        return mainBinding.root
    }

    override fun initView(savedInstanceState: Bundle?) {
        cameraExecutor = Executors.newSingleThreadExecutor()

        // 请求相机权限
        if (allPermissionsGranted()) {
            startCamera(BACK_CAMERA)
        } else {
            ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
        }
    }

    override fun initData() {
        RfidManager.connectDevice {
            RfidManager.readeTag()
        }
        LedManager.deviceInit(LedManager.COM_NAME, 19200, object : InitDeviceCallback {
            override fun initSuccess() {
            }

            override fun initFailed() {
            }
        })
        handler.postDelayed(runnable, 20000)
    }

    override fun setListener() {
        mainBinding.resetBt.setOnClickListener {
            val cmd = CMD.getCmd("禁止", "禁止通行", CMD.TC_RED)
            ComPort.getInstance().sendData(cmd)
            viewModel.verifyPassageAuthority("4") { status, vin ->
            }
        }
        mainBinding.readBt.setOnClickListener { //            RfidManager.readeTag()
            viewModel.isEnablePhoto(true)
        }
        mainBinding.stopBt.setOnClickListener {

            //            RfidManager.stopRead()
            //            isReading = false
            //            val cmd = CMD.getCmd("禁止", "禁止通行", CMD.TC_RED)
            //            ComPort.getInstance().sendData(cmd)
        }
    }

    override fun createObserver() {
        frontImagePath.observe(this) { absolutePath ->
            viewModel.getUploadUrl {
                LogFileUtils.writeTxtToFile("车头照片上传获取连接：$it")
                val frontPic = File(absolutePath)
                viewModel.uploadImage(frontPic, it?.url ?: "", it?.token ?: "") { key ->
                    LogFileUtils.writeTxtToFile("车头照片上传成功：$key")
                    val frontPicName = "${VehicleState.APPROACHING.name}.jpeg"
                    viewModel.uploadImageFinish(key ?: "",
                        it?.requestId ?: "",
                        frontPicName) { resId ->
                        LogFileUtils.writeTxtToFile("车头照片上传完成请求：$resId")
                        outFrontResId = resId
                        requestSync(resId)
                    }
                }
            }
        }
        bodyImagePath.observe(this) { absolutePath ->
            viewModel.getUploadUrl {
                LogFileUtils.writeTxtToFile("车身照片上传获取连接：$it")
                val bodyPic = File(absolutePath)
                viewModel.uploadImage(bodyPic, it?.url ?: "", it?.token ?: "") { key ->
                    LogFileUtils.writeTxtToFile("车身照片上传成功：$key")
                    val bodyPicName = "${VehicleState.CENTERED.name}.jpeg"
                    viewModel.uploadImageFinish(key ?: "",
                        it?.requestId ?: "",
                        bodyPicName) { resId ->
                        LogFileUtils.writeTxtToFile("车身照片上传完成请求：$resId")
                        outMiddleResId = resId
                    }
                }
            }
        }
        rearImagePath.observe(this) { absolutePath ->
            viewModel.getUploadUrl {
                LogFileUtils.writeTxtToFile("车尾照片上传获取连接：$it")
                val rearPic = File(absolutePath)
                viewModel.uploadImage(rearPic, it?.url ?: "", it?.token ?: "") { key ->
                    LogFileUtils.writeTxtToFile("车尾照片上传成功：$key")
                    val rearPicName = "${VehicleState.DONE.name}.jpeg"
                    viewModel.uploadImageFinish(key ?: "",
                        it?.requestId ?: "",
                        rearPicName) { resId ->
                        LogFileUtils.writeTxtToFile("车尾照片上传完成请求：$resId")
                        outEndResId = resId
                    }
                }
            }
        }
        /**
         * 读取标签监听
         */
        RfidManager.result.observe(this) {
            if (!isVerifying) {
                if (epcSet.contains(it.epc)) {
                    return@observe
                } else {
                    val uid = it.epc
                    LogFileUtils.writeTxtToFile("扫到新标签：${uid}")
                    isVerifying = true
                    epcSet.add(uid)
                    viewModel.verifyPassageAuthority(uid) { status, vin ->
                        val stockStatus: StockStatus? = try { // 尝试将字符串转换为 StockStatus 枚举实例
                            // 请注意，如果 result 字符串与任何枚举名称不匹配，valueOf() 会抛出 IllegalArgumentException
                            StockStatus.valueOf(status)
                        } catch (e: IllegalArgumentException) {
                            Log.e("StockStatus", "未知或无效的 StockStatus 字符串: $status", e)
                            null // 转换失败时设为 null，以便在 else 中处理
                        }
                        when (stockStatus) {
                            StockStatus.IN_STOCK -> {
                                LogFileUtils.writeTxtToFile("${uid}没有通行权限")
                                val cmd = CMD.getCmd("禁止", "禁止通行", CMD.TC_RED)
                                ComPort.getInstance().sendData(cmd)
                                isVerifying = false
                            }
                            StockStatus.OUTING -> {
                                carEntity.uid = uid
                                carEntity.inOutStatus = 1 //出库
                                LogFileUtils.writeTxtToFile("${uid}有通行权限")
                                val cmd = CMD.getCmd("通行", "一路平安", CMD.TC_GREEN)
                                ComPort.getInstance().sendData(cmd)
                                startCamera(BACK_CAMERA)
                                viewModel.isEnablePhoto(true)
                            }
                            StockStatus.OUT_STOCK -> {
                            }
                            else -> {
                                carEntity.uid = uid
                                carEntity.inOutStatus = 0 //入库
                                startCamera(FRONT_CAMERA)
                                viewModel.isEnablePhoto(true)
                            }
                        }
                    }
                }
            }
        }
    }


    private fun startCamera(cameraType: Int) {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // 1. 获取摄像头管理服务，用于查询ImageCapture支持的分辨率
            val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
            var largestImageCaptureSize: Size? =
                null // Determine target lens facing based on the 'camera' parameter
            val targetLensFacing = when (cameraType) {
                FRONT_CAMERA -> CameraSelector.LENS_FACING_FRONT
                else -> CameraSelector.LENS_FACING_BACK
            }

            try { // 2. 查找后置摄像头的ID
                var backCameraId: String? = null
                for (id in cameraManager.cameraIdList) {
                    val characteristics = cameraManager.getCameraCharacteristics(id)
                    val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
                    if (facing != null && facing == targetLensFacing) {
                        backCameraId = id
                        break
                    }
                }

                if (backCameraId != null) {
                    val characteristics =
                        cameraManager.getCameraCharacteristics(backCameraId) // 3. 获取流配置映射
                    val map =
                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)

                    // NEW: 获取ImageCapture (JPEG) 支持的所有输出尺寸
                    val captureOutputSizes: Array<Size>? = map?.getOutputSizes(ImageFormat.JPEG)

                    if (!captureOutputSizes.isNullOrEmpty()) { // 从拍照尺寸中选择像素面积最大的
                        largestImageCaptureSize =
                            captureOutputSizes.maxByOrNull { it.width * it.height }
                        Log.d(TAG,
                            "Found largest supported resolution for ImageCapture: ${largestImageCaptureSize?.width}x${largestImageCaptureSize?.height}")
                        LogFileUtils.writeTxtToFile("ImageCapture支持的最大分辨率：${largestImageCaptureSize?.width}x${largestImageCaptureSize?.height}")
                    } else {
                        Log.w(TAG, "No JPEG output sizes found for ImageCapture.")
                        LogFileUtils.writeTxtToFile("没有找到ImageCapture支持的分辨率")
                    }

                } else {
                    Log.e(TAG, "Back camera not found on this device.")
                    LogFileUtils.writeTxtToFile("后置摄像头未找到")
                }
            } catch (e: CameraAccessException) {
                Log.e(TAG, "Camera access exception when querying characteristics: ${e.message}", e)
                Toast.makeText(this, "相机访问异常: ${e.message}", Toast.LENGTH_LONG).show()
                LogFileUtils.writeTxtToFile("相机访问异常: ${e.message}")
            } catch (e: NullPointerException) {
                Log.e(TAG,
                    "NullPointerException when getting camera characteristics or map: ${e.message}",
                    e)
                Toast.makeText(this, "获取相机信息失败", Toast.LENGTH_LONG).show()
                LogFileUtils.writeTxtToFile("获取相机信息失败")
            }


            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(mainBinding.previewView.surfaceProvider)
            }

            val imageCaptureBuilder = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) // 旨在最高质量

            if (largestImageCaptureSize != null) {
                imageCaptureBuilder.setTargetResolution(largestImageCaptureSize)
            } else {
                Log.w(TAG,
                    "Could not determine largest capture resolution, falling back to 1920x1080 for ImageCapture.")
                imageCaptureBuilder.setTargetResolution(Size(1920, 1080)) // 拍照的常用回退分辨率
            }
            imageCapture = imageCaptureBuilder.build()


            // ImageAnalysis Use Case
            // Modified: Pass a lambda to VehicleAnalyzer for photo capture triggering
            analyzer = when (cameraType) {
                FRONT_CAMERA -> VehicleAnalyzerLeftToRight(this,
                    mainBinding.previewView,
                    { stateName ->
                        viewModel.takePhoto(cameraType, stateName, imageCapture, this)
                    },
                    { status, detections, w, h -> // Existing listener for UI updates
                        runOnUiThread {
                            if (status.isNotEmpty()) {
                                Log.d(TAG,
                                    "发现车辆，status: $status, detections: $detections, w: $w, h: $h")
                            }
                            mainBinding.overlayView.setResults(detections, w, h)
                            mainBinding.statusTextView.text = "状态:\n$status"
                        }
                    })
                else -> VehicleAnalyzerRightToLeft(this, mainBinding.previewView, { stateName ->
                    viewModel.takePhoto(cameraType, stateName, imageCapture, this)
                }, { status, detections, w, h -> // Existing listener for UI updates
                    runOnUiThread {
                        if (status.isNotEmpty()) {
                            Log.d(TAG,
                                "发现车辆，status: $status, detections: $detections, w: $w, h: $h")
                        }
                        mainBinding.overlayView.setResults(detections, w, h)
                        mainBinding.statusTextView.text = "状态:\n$status"
                    }
                })
            }
            val imageAnalyzerBuilder = ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)

            // MODIFIED: 为ImageAnalysis用例设置一个较低但有利于识别效率的固定分辨率
            // 640x480 (VGA) 或 1280x720 (720p) 是常见且高效的选择
            val analysisResolution = Size(640, 480) // 示例：VGA分辨率
            imageAnalyzerBuilder.setTargetResolution(analysisResolution)
            Log.d(TAG,
                "ImageAnalysis will use fixed resolution: ${analysisResolution.width}x${analysisResolution.height}")
            Toast.makeText(this,
                "分析分辨率固定为: ${analysisResolution.width}x${analysisResolution.height}",
                Toast.LENGTH_LONG).show()


            val imageAnalyzer = imageAnalyzerBuilder.build().also {
                it.setAnalyzer(cameraExecutor, analyzer as ImageAnalysis.Analyzer)
            }
            val cameraSelector = when (cameraType) {
                FRONT_CAMERA -> CameraSelector.DEFAULT_FRONT_CAMERA
                else -> CameraSelector.DEFAULT_BACK_CAMERA
            }

            try {
                cameraProvider.unbindAll() // Bind all three use cases: Preview, ImageAnalysis, ImageCapture
                val camera = cameraProvider.bindToLifecycle(this,
                    cameraSelector,
                    preview,
                    imageAnalyzer,
                    imageCapture)

                // --- 相机对焦功能 ---
                // 启用连续自动对焦 (CAF)
                val factory =
                    SurfaceOrientedMeteringPointFactory(analysisResolution.width.toFloat(),
                        analysisResolution.height.toFloat())
                val centerPoint = factory.createPoint(analysisResolution.width / 2f,
                    analysisResolution.height / 2f)
                val focusMeteringAction =
                    FocusMeteringAction.Builder(centerPoint, FocusMeteringAction.FLAG_AF).build()
                camera.cameraControl.startFocusAndMetering(focusMeteringAction)

            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
                Toast.makeText(this, "相机绑定失败: ${exc.message}", Toast.LENGTH_LONG).show()
            }

        }, ContextCompat.getMainExecutor(this))
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    // ... 权限请求的回调处理 ...
    override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startCamera(BACK_CAMERA)
            } else { // 用户未授予权限，提示并关闭应用
            }
        }
    }

    private fun requestSync(resId: String) {
        carEntity.resId = resId
        carEntity.uid = "4"
        viewModel.synchronizeOutStockInfo(carEntity) { //数据同步后重置
            isVerifying = false
            outFrontResId = ""
            outMiddleResId = ""
            outEndResId = ""
        }
        viewModel.isEnablePhoto(false)
    }

    companion object {
        val frontImagePath = MutableLiveData<String>()
        val bodyImagePath = MutableLiveData<String>()
        val rearImagePath = MutableLiveData<String>()
        private const val FRONT_CAMERA = 0
        private const val BACK_CAMERA = 1
        private const val TAG = "MainActivity"
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
    }

    private val handler = Handler()
    private val runnable: Runnable = object : Runnable {
        override fun run() {
            epcSet.clear() //两分钟清一下缓存标签，否则进入缓存的标签不再进入查询权限
            handler.removeCallbacks(this)
            currentCamera = if (currentCamera == 1) 0 else 1
            startCamera(currentCamera)
            handler.postDelayed(this, 20 * 1000)
        }
    }

    override fun onResume() {
        super.onResume()
        LogFileUtils.writeTxtToFile("成功启动")
    }
}